using System;
using UnityEngine;

namespace DanielSig.UnityExtensions
{
	public static class XVector4
	{
		#region REORDER
		#region VECTOR 2
		public static Vector2 XX(this Vector4 v){ return new Vector2(v.x, v.x); }
		public static Vector2 XY(this Vector4 v){ return new Vector2(v.x, v.y); }
		public static Vector2 XZ(this Vector4 v){ return new Vector2(v.x, v.z); }
		public static Vector2 XW(this Vector4 v){ return new Vector2(v.x, v.w); }
		public static Vector2 YX(this Vector4 v){ return new Vector2(v.y, v.x); }
		public static Vector2 YY(this Vector4 v){ return new Vector2(v.y, v.y); }
		public static Vector2 YZ(this Vector4 v){ return new Vector2(v.y, v.z); }
		public static Vector2 YW(this Vector4 v){ return new Vector2(v.y, v.w); }
		public static Vector2 ZX(this Vector4 v){ return new Vector2(v.z, v.x); }
		public static Vector2 ZY(this Vector4 v){ return new Vector2(v.z, v.y); }
		public static Vector2 ZZ(this Vector4 v){ return new Vector2(v.z, v.z); }
		public static Vector2 ZW(this Vector4 v){ return new Vector2(v.z, v.w); }
		public static Vector2 WX(this Vector4 v){ return new Vector2(v.w, v.x); }
		public static Vector2 WY(this Vector4 v){ return new Vector2(v.w, v.y); }
		public static Vector2 WZ(this Vector4 v){ return new Vector2(v.w, v.z); }
		public static Vector2 WW(this Vector4 v){ return new Vector2(v.w, v.w); }
		#endregion
		
		#region VECTOR 3
		public static Vector3 XXX(this Vector4 v){ return new Vector3(v.x, v.x, v.x); }
		public static Vector3 XXY(this Vector4 v){ return new Vector3(v.x, v.x, v.y); }
		public static Vector3 XXZ(this Vector4 v){ return new Vector3(v.x, v.x, v.z); }
		public static Vector3 XXW(this Vector4 v){ return new Vector3(v.x, v.x, v.w); }
		public static Vector3 XYX(this Vector4 v){ return new Vector3(v.x, v.y, v.x); }
		public static Vector3 XYY(this Vector4 v){ return new Vector3(v.x, v.y, v.y); }
		public static Vector3 XYZ(this Vector4 v){ return new Vector3(v.x, v.y, v.z); }
		public static Vector3 XYW(this Vector4 v){ return new Vector3(v.x, v.y, v.w); }
		public static Vector3 XZX(this Vector4 v){ return new Vector3(v.x, v.z, v.x); }
		public static Vector3 XZY(this Vector4 v){ return new Vector3(v.x, v.z, v.y); }
		public static Vector3 XZZ(this Vector4 v){ return new Vector3(v.x, v.z, v.z); }
		public static Vector3 XZW(this Vector4 v){ return new Vector3(v.x, v.z, v.w); }
		public static Vector3 XWX(this Vector4 v){ return new Vector3(v.x, v.w, v.x); }
		public static Vector3 XWY(this Vector4 v){ return new Vector3(v.x, v.w, v.y); }
		public static Vector3 XWZ(this Vector4 v){ return new Vector3(v.x, v.w, v.z); }
		public static Vector3 XWW(this Vector4 v){ return new Vector3(v.x, v.w, v.w); }
		
		public static Vector3 YXX(this Vector4 v){ return new Vector3(v.y, v.x, v.x); }
		public static Vector3 YXY(this Vector4 v){ return new Vector3(v.y, v.x, v.y); }
		public static Vector3 YXZ(this Vector4 v){ return new Vector3(v.y, v.x, v.z); }
		public static Vector3 YXW(this Vector4 v){ return new Vector3(v.y, v.x, v.w); }
		public static Vector3 YYX(this Vector4 v){ return new Vector3(v.y, v.y, v.x); }
		public static Vector3 YYY(this Vector4 v){ return new Vector3(v.y, v.y, v.y); }
		public static Vector3 YYZ(this Vector4 v){ return new Vector3(v.y, v.y, v.z); }
		public static Vector3 YYW(this Vector4 v){ return new Vector3(v.y, v.y, v.w); }
		public static Vector3 YZX(this Vector4 v){ return new Vector3(v.y, v.z, v.x); }
		public static Vector3 YZY(this Vector4 v){ return new Vector3(v.y, v.z, v.y); }
		public static Vector3 YZZ(this Vector4 v){ return new Vector3(v.y, v.z, v.z); }
		public static Vector3 YZW(this Vector4 v){ return new Vector3(v.y, v.z, v.w); }
		public static Vector3 YWX(this Vector4 v){ return new Vector3(v.y, v.w, v.x); }
		public static Vector3 YWY(this Vector4 v){ return new Vector3(v.y, v.w, v.y); }
		public static Vector3 YWZ(this Vector4 v){ return new Vector3(v.y, v.w, v.z); }
		public static Vector3 YWW(this Vector4 v){ return new Vector3(v.y, v.w, v.w); }
		
		public static Vector3 ZXX(this Vector4 v){ return new Vector3(v.z, v.x, v.x); }
		public static Vector3 ZXY(this Vector4 v){ return new Vector3(v.z, v.x, v.y); }
		public static Vector3 ZXZ(this Vector4 v){ return new Vector3(v.z, v.x, v.z); }
		public static Vector3 ZXW(this Vector4 v){ return new Vector3(v.z, v.x, v.w); }
		public static Vector3 ZYX(this Vector4 v){ return new Vector3(v.z, v.y, v.x); }
		public static Vector3 ZYY(this Vector4 v){ return new Vector3(v.z, v.y, v.y); }
		public static Vector3 ZYZ(this Vector4 v){ return new Vector3(v.z, v.y, v.z); }
		public static Vector3 ZYW(this Vector4 v){ return new Vector3(v.z, v.y, v.w); }
		public static Vector3 ZZX(this Vector4 v){ return new Vector3(v.z, v.z, v.x); }
		public static Vector3 ZZY(this Vector4 v){ return new Vector3(v.z, v.z, v.y); }
		public static Vector3 ZZZ(this Vector4 v){ return new Vector3(v.z, v.z, v.z); }
		public static Vector3 ZZW(this Vector4 v){ return new Vector3(v.z, v.z, v.w); }
		public static Vector3 ZWX(this Vector4 v){ return new Vector3(v.z, v.w, v.x); }
		public static Vector3 ZWY(this Vector4 v){ return new Vector3(v.z, v.w, v.y); }
		public static Vector3 ZWZ(this Vector4 v){ return new Vector3(v.z, v.w, v.z); }
		public static Vector3 ZWW(this Vector4 v){ return new Vector3(v.z, v.w, v.w); }
		
		public static Vector3 WXX(this Vector4 v){ return new Vector3(v.w, v.x, v.x); }
		public static Vector3 WXY(this Vector4 v){ return new Vector3(v.w, v.x, v.y); }
		public static Vector3 WXZ(this Vector4 v){ return new Vector3(v.w, v.x, v.z); }
		public static Vector3 WXW(this Vector4 v){ return new Vector3(v.w, v.x, v.w); }
		public static Vector3 WYX(this Vector4 v){ return new Vector3(v.w, v.y, v.x); }
		public static Vector3 WYY(this Vector4 v){ return new Vector3(v.w, v.y, v.y); }
		public static Vector3 WYZ(this Vector4 v){ return new Vector3(v.w, v.y, v.z); }
		public static Vector3 WYW(this Vector4 v){ return new Vector3(v.w, v.y, v.w); }
		public static Vector3 WZX(this Vector4 v){ return new Vector3(v.w, v.z, v.x); }
		public static Vector3 WZY(this Vector4 v){ return new Vector3(v.w, v.z, v.y); }
		public static Vector3 WZZ(this Vector4 v){ return new Vector3(v.w, v.z, v.z); }
		public static Vector3 WZW(this Vector4 v){ return new Vector3(v.w, v.z, v.w); }
		public static Vector3 WWX(this Vector4 v){ return new Vector3(v.w, v.w, v.x); }
		public static Vector3 WWY(this Vector4 v){ return new Vector3(v.w, v.w, v.y); }
		public static Vector3 WWZ(this Vector4 v){ return new Vector3(v.w, v.w, v.z); }
		public static Vector3 WWW(this Vector4 v){ return new Vector3(v.w, v.w, v.w); }
		#endregion
		#endregion
		
		public static String ToStringSharp4(this Vector4 v, int numFractions)
		{
			float power = Mathf.Pow(10F, (float)numFractions);
			float invPower = 1F / power;
			v *= power;
			v.x = ((int)v.x) * invPower;
			v.y = ((int)v.y) * invPower;
			v.z = ((int)v.z) * invPower;
			v.w = ((int)v.w) * invPower;
			return "(" + v.x + ", " + v.y + ", " + v.z + ", " + v.w + ")";
		}
		public static String ToStringSharp4(this Vector4 v)
		{
			return v.ToStringSharp(3);
		}
		
		public static Vector3 ToVector3(this Vector4 v)
		{
			return new Vector3(v.x, v.y, v.z);
		}
		public static Vector2 ToVector2(this Vector4 v)
		{
			return new Vector2(v.x, v.y);
		}
		public static Vector2[] ToVector2s(this Vector4 v)
		{
			return new Vector2[] { new Vector2(v.x, v.y), new Vector2(v.z, v.w) };
		}
		public static Plane ToPlane(this Vector4 v)
		{
			return new Plane(v.ToVector3(), v.w);
		}
		public static Vector4 Abs(this Vector4 v)
		{
			return new Vector4(v.x > 0 ? v.x : -v.x, v.y > 0 ? v.y : -v.y, v.z > 0 ? v.z : -v.z, v.w > 0 ? v.w : -v.w);
		}
		public static Vector4 Add(this Vector4 v, float x, float y, float z)
		{
			v.x += x;
			v.y += y;
			v.z += z;
			return v;
		}
		public static Vector4 AddX(this Vector4 v, float value)
		{
			v.x += value;
			return v;
		}
		public static Vector4 AddY(this Vector4 v, float value)
		{
			v.y += value;
			return v;
		}
		public static Vector4 AddZ(this Vector4 v, float value)
		{
			v.z += value;
			return v;
		}
		public static Vector4 AddW(this Vector4 v, float value)
		{
			v.w += value;
			return v;
		}
		public static Vector4 Scale(this Vector4 v, float x, float y, float z, float w)
		{
			v.x *= x;
			v.y *= y;
			v.z *= z;
			v.w *= w;
			return v;
		}
		public static Vector4 ScaleX(this Vector4 v, float scale)
		{
			v.x *= scale;
			return v;
		}
		public static Vector4 ScaleY(this Vector4 v, float scale)
		{
			v.y *= scale;
			return v;
		}
		public static Vector4 ScaleZ(this Vector4 v, float scale)
		{
			v.z *= scale;
			return v;
		}
		public static Vector4 ScaleW(this Vector4 v, float scale)
		{
			v.w *= scale;
			return v;
		}
	}
}

